# 1. 添加cmake版本说明
cmake_minimum_required(VERSION 3.1.3)
# 2. 声明工程名称
project(user-server)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)  # 强制要求 C++17，不存在则报错
set(CMAKE_CXX_EXTENSIONS OFF)  # 禁用编译器扩展（如 gnu++17）

set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/local/lib)

set(target "friendServer")
set(test_client "friendClient")

set(util_path ${CMAKE_CURRENT_SOURCE_DIR}/../util)
set(common_path ${CMAKE_CURRENT_SOURCE_DIR}/../common)
set(odb_path ${CMAKE_CURRENT_SOURCE_DIR}/../odb)
set(proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../proto)
set(mysql_path ${CMAKE_CURRENT_SOURCE_DIR}/../mysql)
set(thrid_path ${CMAKE_CURRENT_SOURCE_DIR}/../thrid)

# 3. 检测并生成proto框架代码
#   1. 添加所需的proto映射代码文件名称
set(proto_files base.proto user.proto message.proto friend.proto)
#   2. 检测框架代码文件是否已经生成
set(proto_h "")
set(proto_cc "")
set(proto_srcs "")
foreach(proto_file ${proto_files})
#   3. 如果没有生成，则预定义生成指令 -- 用于在构建项目之间先生成框架代码
    string(REPLACE ".proto" ".pb.h" proto_h ${proto_file})
    string(REPLACE ".proto" ".pb.cc" proto_cc ${proto_file})
    if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}${proto_cc})
        add_custom_command(
            PRE_BUILD
            COMMAND protoc
            ARGS --cpp_out=${CMAKE_CURRENT_BINARY_DIR} 
                 --experimental_allow_proto3_optional
                 -I ${proto_path} ${proto_file}
            DEPENDS ${proto_path}/${proto_file}
            OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc} 
                   ${CMAKE_CURRENT_BINARY_DIR}/${proto_h}
            COMMENT "生成proto框架代码文件:" ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc} 
                                            ${CMAKE_CURRENT_BINARY_DIR}/${proto_h}
        )
    endif()
#   4. 将所有生成的框架源码文件名称保存起来 student-proto.cxx classes-proto.cxx
    list(APPEND proto_srcs ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc})
endforeach()

# 4. 检测并生成ODB框架代码
#   1. 添加所需的odb映射代码文件名称
set(odb_files chat_session_member.hxx chat_session_info.hxx friend_request.hxx relationship.hxx)
#   2. 检测框架代码文件是否已经生成
set(odb_srcs "")

foreach(odb_file ${odb_files})
    # 提取文件名（不含扩展名）用于生成ODB输出文件
    string(REPLACE ".hxx" "" base_name ${odb_file})
    
    set(odb_hxx "${CMAKE_CURRENT_BINARY_DIR}/${base_name}-odb.hxx")
    set(odb_cxx "${CMAKE_CURRENT_BINARY_DIR}/${base_name}-odb.cxx")
    
    
    add_custom_command(
        OUTPUT ${odb_cxx} ${odb_hxx}
        COMMAND odb -d mysql --std c++11 --generate-query --generate-schema
                --profile boost/date-time
                --output-dir ${CMAKE_CURRENT_BINARY_DIR}
                ${odb_path}/${odb_file}
        DEPENDS ${odb_path}/${odb_file}
        COMMENT "Generating ODB files for ${odb_file}"
    )
    
    list(APPEND odb_srcs ${odb_cxx})
endforeach()

# 4. 获取源码目录下的所有源码文件
set(server_src_files "")
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source server_src_files)

set(client_src_files "")
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/test client_src_files)

# 5. 声明目标及依赖
list(APPEND server_src_files ${common_path}/log.cpp 
                      ${common_path}/etcd.cpp
                      ${common_path}/channel.cpp
                      ${common_path}/elastic.cpp
                      ${common_path}/data_es.cpp
                      ${mysql_path}/mysql_friend_request.cpp
                      ${mysql_path}/mysql_relationship.cpp
                      ${mysql_path}/mysql_session_info.cpp
                      ${mysql_path}/mysql_session.cpp
                      ${util_path}/uuid.cpp
                      ${util_path}/cjson.cpp)


list(APPEND client_src_files ${common_path}/log.cpp 
                            ${common_path}/etcd.cpp
                            ${common_path}/channel.cpp
                            ${util_path}/uuid.cpp )


# 7. 设置需要连接的库
add_executable(${target} ${server_src_files} ${proto_srcs} ${odb_srcs})
target_link_libraries(${target} -lbrpc -lprotobuf -lgflags -lssl -lcrypto 
                                -lleveldb -lspdlog -lfmt -letcd-cpp-api 
                                -lcpprest -lcurl 
                                -lodb-mysql -lodb -lodb-boost
                                -lcpr -lelasticlient /usr/local/lib/libjsoncpp.so)


add_executable(${test_client} ${client_src_files} ${proto_srcs} ${odb_srcs})
target_link_libraries(${test_client} -lbrpc -lprotobuf -lgflags -lssl -lcrypto 
                                -lleveldb -lspdlog -lfmt -letcd-cpp-api 
                                -lcpprest -lcurl 
                                -lodb-mysql -lodb -lodb-boost
                                -lcpr -lelasticlient /usr/local/lib/libjsoncpp.so
                                -lgtest)
                                
# 6. 设置头文件默认搜索路径
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${util_path})
include_directories(${common_path})
include_directories(${odb_path})
include_directories(${mysql_path})
include_directories(${thrid_path})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/source)

#8. 设置安装路径
INSTALL(TARGETS ${target} ${test_client} RUNTIME DESTINATION bin)
# INSTALL(TARGETS ${target}  RUNTIME DESTINATION bin)